import config, {
  bash_url
} from '../config/config'

import store from '@/store/'

let v = config.v

// 请求头
let header = {
  // "content-type": "application/x-www-form-urlencoded"
}

/**
 * @参数说明
 * url: 接口路径
 * method： 接口类型 默认get类型
 * data: 接口请求数据
 * headerParam: 是否需要添加默认请求头参数
 * loading: 是否需要加载loading
 */

let interruptTime

const requestApi =
  ({
    url,
    method = 'get',
    data,
    headerParam = true,
    loading = false,
    proxy = true,
    interrupt = false,
    pageLoading = false
  }) => new Promise((resolve, reject) => {

    /**
     * @接口中断判断 interrupt
     * 如果 interrupt 为true 表示 这个接口 在规定时间内只能 执行一次
     * 同时可以用作接口防抖
     * 
     */
    // 如果当前接口需要做中断处理
    if (pageLoading) {
      store.state.pageApiLoading = true
    }
    if (interrupt) {
      // 判断是否有 上一次是否有接口短时间进行过处理
      if (interruptTime) {
        // 判断上一次执行时间比当前时间是否小于30秒，小于30秒则中断请求
        if (new Date() - interruptTime < 30 * 1000) {
          // 获取剩余时间
          const s = parseInt((new Date() - interruptTime) / 1000)
          if (method == 'post') {

            uni.showToast({
              title: `操作频繁请${s}秒后再试试吧！`,
              icon: 'none',
              duration: 3 * 1000
            })
          }
          return
        }
      }
      // 如果 是可以执行的，那么保存当前执行时间给下一个判断使用
      interruptTime = new Date()
    }

    /**
     * @代理判断
     * proxy：接口表示是否需要代理，
     *    如果为true表示需要代理。走代理的服务器，在后缀上加上xx简称
     *    false 表示是直接去储存登录用户信息的服务器
     */
    const {
      userInfor
    } = store.state

    const bash = bash_url['proxy']
    // 需要走代理 在链接上加上名字

    let bashUrl = `${bash.https ? 'https' : 'http'}://${bash.url}`

    // 判断是否需要请求头
    // 默认是需要请求头，如果有不需要的接口，那么接口传headerParam为false，就会直接发送接口请求。
    if (headerParam) {
      // 获取 用户信息
      // let {
      //   openid
      // } = userInfor
    }

    let showLoading = true // 判断 showLoading 是否还在继续加载

    // 判断是否需要加载loading出现
    if (loading) {
      uni.showLoading({
        title: method == "get" ? '加载中' : '发送中',
        mask: true
      })

      // 防止请求时间过长。设置超时机制
      setTimeout(() => {
        if (showLoading) { // 如果还在加载 那么超时关闭
          uni.hideLoading()
          failToast(loading)
          reject()
        }
      }, 20 * 1000) // 超时时间
    }

    uni.request({
      url: `${bashUrl}${url}`,
      method,
      data,
      header,
      success: res => { 
        showLoading = false
        // 统一处理状态码，状态码符合才继续走下一步逻辑
        if (res.statusCode == 200 && res.data.code == 0) {
          // 正常流程，表示请求成功
          resolve(res.data)
        } else if (res.data.code == 2) {
          // 用户流程出现问题，用code = 2表示，然后将 msg 打印出来，
          failToast(loading, res.data.message)
        } else if (res.data.code == 3) {
          // 用户流程出现问题，用code = 3 表示，但是不需要展示报错信息。直接交给请求的地方处理逻辑。 直接执行错误的返回函数
          reject(res.data)
        } else {
          // 以下处理其他异常情况统一的报错
          failToast(loading, res.data.message)
        }
        // 延迟一下loading， 防止 加载太快 loading一闪而过
        setTimeout(() => {
          // 不管成功还是失败 都需要重置他的状态
          uni.hideLoading()
        }, 2000)

      },
      fail: err => {
        showLoading = false
        failToast(loading)
        // promise 反馈失败
        reject(err)
      },
      complete() {
        // 不管请求失败还是成功，如果 这个接口是需要中断类型的接口，那么都需要interruptTime 重置 表示上一次 该类型接口已经执行完毕，可以执行下一个接口
        setTimeout(() => {
          if (interrupt) {
            interruptTime = null
          }
        }, 2000)

        // 不管接口请求失败还是成功，都让页面显示出来
        setTimeout(() => {
          if (pageLoading) {
            store.state.pageApiLoading = false
          }
        }, 2000)
      }
    })
  })

// 默认反馈文字为 请求失败
function failToast(loading, errText = '加载出现一点问题，请重试') {
  if (loading) {
    uni.showToast({
      title: errText,
      icon: 'none',
      duration: (errText ? 3 : 1.5) * 1000
    })
  }
}

export default requestApi